PHP: Database gets & calls (PDO)
December 1, 2020
PDO
object)PDO
methods, return PDOStatement
object)PDOStatement
methods)
PDO::setAttribute
)htmlentities()
PDO::quote
PDO::prepare
+ PDOStatement::execute
<?php
// Logical part
try {
$error = null;
$dsn = __DIR__ . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR . 'data.db';
$pdo = new PDO(
"sqlite:$dsn", null, null, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // To be able to catch method-level exceptions
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ // To get an object from the fetch operation (instead of the default array)
]);
try {
$query = $pdo->query('SELECT * FROM posts ORDER BY date_creation DESC');
$posts_obj = $query->fetchAll(); // Various fetch operations can be applied here: check lesson to get a list
} catch (Exception $e) { // Catch exceptions thrown from the method ("query") level
$error = '<b>Error message:</b> ' . $e->getMessage();
}
} catch (PDOException $e) { // Catch exceptions thrown from the new PDO instantiation level
$error = 'Error message: ' . $e->getMessage();;
}
// Displaying part ?>
<?php if ($error): ?>
<div class="alert alert-danger"><?= $error?></div>
<?php else: ?>
<p>Latest posts:</p>
<ul>
<?php foreach ($posts_obj as $post): ?>
<?php $date = new DateTime("@{$post->date_creation}"); ?>
<li><?= '<b>' . $post->title . '</b>' .
' on ' . $date->format('M d, Y (H:i)') .
'<div style="font-size:11px;line-height:15px;margin-bottom:5px">' .
$post->content .
'</div>' ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
<?php // End of code
Latest posts:
new PDO(‘sqlite:../data.db’);
<?php
/* Connect to a MySQL database using driver invocation */
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
try {
$pdo = new PDO($dsn, $user, $password);
} catch (PDOException $e) { // Use a try/catch to manage exceptions
echo 'Connection failed: ' . $e->getMessage();
}
?>
$pdo = new PDO('sqlite:../data.db');
$query = $pdo->query('SELECT * FROM posts');
if ($query === false) {
var_dump($pdo->errorInfo()); // Display error message during the development stage
// do more stuff
}
PDOStatement
class$dsn = __DIR__ . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR . 'data.db';
try {
$pdo = new PDO("sqlite:$dsn");
$query = $pdo->query('SELECT * FROM posts');
if ($query === false) { // PDOStatement object returns "false" in case of error
echo '<b>Query Error:</b><pre>'; print_r($pdo->errorInfo()); echo '</pre>';
} else {
$posts = $query->fetchAll();
echo ''; var_dump($posts); echo '
'; // Display all the table content in default style
}
} catch (Exception $e) { // Catch an Exception in case of failure connecting to database
echo '<b>Connection failed:</b> ' . $e->getMessage();
}
array(3) { [0]=> array(8) { ["id"]=> string(1) "1" [0]=> string(1) "1" ["title"]=> string(25) "This is a blog post title" [1]=> string(25) "This is a blog post title" ["content"]=> string(214) "Lorem ipsum dolor, sit amet consectetur adipisicing elit. Incidunt ut, aperiam ea ducimus iste est nihil corporis repudiandae doloribus maiores quos! Necessitatibus alias ad odit quam sed voluptas voluptatibus vel." [2]=> string(214) "Lorem ipsum dolor, sit amet consectetur adipisicing elit. Incidunt ut, aperiam ea ducimus iste est nihil corporis repudiandae doloribus maiores quos! Necessitatibus alias ad odit quam sed voluptas voluptatibus vel." ["date_creation"]=> string(10) "1601579987" [3]=> string(10) "1601579987" } [1]=> array(8) { ["id"]=> string(1) "2" [0]=> string(1) "2" ["title"]=> string(11) "Lorem Ipsum" [1]=> string(11) "Lorem Ipsum" ["content"]=> string(58) "This is some dumb content for post 2, for testing purpose!" [2]=> string(58) "This is some dumb content for post 2, for testing purpose!" ["date_creation"]=> string(10) "1604776787" [3]=> string(10) "1604776787" } [2]=> array(8) { ["id"]=> string(1) "3" [0]=> string(1) "3" ["title"]=> string(10) "Test title" [1]=> string(10) "Test title" ["content"]=> string(12) "Test content" [2]=> string(12) "Test content" ["date_creation"]=> string(10) "1606847434" [3]=> string(10) "1606847434" } }
$dsn = __DIR__ . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR . 'data.db';
try {
$pdo = new PDO("sqlite:$dsn");
// Return last posts on top of list:
$query = $pdo->query('SELECT * FROM posts ORDER BY date_creation DESC');
if ($query === false) {
echo '<b>Query Error:</b><pre>'; print_r($pdo->errorInfo()); echo '</pre>';
} else {
// Return database content into an object:
$posts_obj = $query->fetchAll(PDO::FETCH_OBJ);
?>
Latest posts:
<ul>
// Go throught each post one by one to extract specific content:
<?php foreach ($posts_obj as $post): ?>
// Then display each element separatly:
<?php $date = new DateTime("@{$post->date_creation}"); ?>
<li>
<?= '<b>' . $post->title . '</b>' .
' on ' . $date->format('M d, Y (H:i)') .
'<div style="font-size:11px;line-height:15px;margin-bottom: 5px">' .
$post->content .
'</div>' ?>
</li>
<?php endforeach; ?>
</ul><?php
}
} catch (Exception $e) {
echo '<b>Connection failed:</b> ' . $e->getMessage();
}
PDO::setAttribute
method)// PDO::setAttribute method's signature from PHP.net:
public PDO::setAttribute ( int $attribute , mixed $value ) : bool
// Application example:
$pdo = new PDO("mysql:host=$host; dbname=$dbname", $db_username, $db_password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$query = $pdo->query('SELECT * FROM posts ORDER BY date_creation DESC');
// Will return an Exception instead of a fatal error in case of failure
// PDO class's signature from PHP.net:
public PDO::__construct ( string $dsn [, string $username [, string $passwd [, array $options ]]] )
// Application exemple:
try {
// Then pass the options as the last parameter in the connection string
$pdo = new PDO(
"mysql:host=$host; dbname=$dbname",
$db_username,
$db_password,
[ // Here can be set as many attributes as needed into an associative array
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // That's how to set a failed result as a nex Exception
PDO::ATTR_CASE => PDO::CASE_NATURAL,
PDO::ATTR_ORACLE_NULLS => PDO::NULL_EMPTY_STRING
]
$query = $pdo->query('SELECT * FROM posts ORDER BY date_creation DESC'); // Will return an Exception instead of a fatal error in case of failure
);
} catch(PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
// Don't do this:
<ul>
<?php foreach($posts as $post): ?>
<li><a href="/blog/edit.php?=id=<?= $post->id ?>"><?= $post->name ?></a></li>
<?php endforeach; ?>
</ul>
// Do this instead:
<ul>
<?php foreach($posts as $post): ?>
<li><a href="/blog/edit.php?=id=<?= $post->id ?>"><?= htmlentities($post->name) ?></a></li>
<?php endforeach; ?>
</ul>
// Don't do this:
$pdo = new PDO( ... );
try {
$query = $pdo->query('SELECT * FROM posts WHERE id = ' . $_GET['id']);
$posts_obj = $query->fetchAll();
} catch (Exception $e) { ... }
// Do this instead:
$pdo = new PDO( ... );
$id = $pdo->quote($_GET['id']);
try {
$query = $pdo->query('SELECT * FROM posts WHERE id = ' . $id);
$posts_obj = $query->fetchAll();
} catch (Exception $e) { ... }
$pdo = new PDO( ... );
// step 1: prepare query with a undefined variable
$query = $pdo->prepare('SELECT * FROM posts WHERE id = :id');
// step 2: define variable and execute
$query->execute([
'id' => $_GET['id']
]);
$post = $query->fetch();
$pdo = new PDO("sqlite:$dsn", null, null, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_OBJ
]);
try {
$pdo->beginTransaction();
$pdo->exec('UPDATE posts SET name = "Test title" WHERE id = 3');
$pdo->exec('UPDATE posts SET content = "Test content" WHERE id = 3');
$post = $pdo->query('SELECT * FROM posts WHERE id = 3')->fetch();
$pdo->commit();
echo '<b>Updated post data:</b>';
var_dump($post);
} catch (Exception $e) {
$pdo->rollback();
echo '<b>No change has been made to database due to a processing error:</b><br>' .
$e->getMessage();
}
object(stdClass)#1 (4) { ["id"]=> string(1) "3" ["title"]=> string(10) "Test title" ["content"]=> string(12) "Test content" ["date_creation"]=> string(10) "1606847434" }